
#include "StdAfx.h"
#include "Celsus.h"
#include "sendmessage.h"
#include "PJNSmtp.h"

CSendMessage::CSendMessage(void)
{
}

CSendMessage::~CSendMessage(void)
{
}


BOOL CSendMessage::ValidateEmail(CString szEmail)
{
	if( szEmail.IsEmpty() )
	{
		AfxMessageBox( _T("Please enter a valid email address in the form of xxx.xxx@xxx.xxx"), MB_OK | MB_ICONSTOP );
		return FALSE;
	}
	// make lower for checking
	szEmail.MakeLower();
	// check for @ sign
	if( szEmail.Find( _T("@") ) == -1 )
	{
		AfxMessageBox( _T("Please enter a valid email address in the form of xxx.xxx@xxx.xxx"), MB_OK | MB_ICONSTOP );
		return FALSE;
	}
	// check for other
	if( szEmail.FindOneOf( _T(",/?'\":;[]{}/\\|") ) != -1 )
	{
		AfxMessageBox( _T("Email addresses can not contain any of the following characters.\r\n\r\n,/?'\":;[]{}/\\|\r\n\r\nPlease enter a valid email address."), MB_OK | MB_ICONSTOP );
		return FALSE;
	}
	// it is good
	return TRUE;
}

BOOL CSendMessage::SendEmail(CString szName, CString szFrom, CString szTo, CString szSubject, CString szBody, CString szAttach)
{
	ASSERT( !szTo.IsEmpty() );
	ASSERT( !szName.IsEmpty() );
	ASSERT( !szFrom.IsEmpty() );
	ASSERT( !szBody.IsEmpty() );

	// Initialize winsock
	WSADATA wsa;
	WSAStartup(MAKEWORD(2,0),&wsa);

	// set wait cursor
	CWaitCursor wait;

	// validate email
	if( !ValidateEmail( szTo ))
		return FALSE;

	BOOL bRetVal = FALSE;
	BOOL m_bDSN = FALSE;
	BOOL bAutoDial = FALSE;
	CString szCC = _T("");
	CString szBCC = _T("");

	//Create the message
	CPJNSMTPConnection connection;
	CPJNSMTPMessage* pMessage = new CPJNSMTPMessage;
	CPJNSMTPBodyPart attachment;

	try
	{
		//Set the mime flag
		pMessage->SetMime( TRUE );

		//Setup the all the recipient types for this message
		pMessage->ParseMultipleRecipients( szTo, pMessage->m_To);
		if( !szCC.IsEmpty() )
			pMessage->ParseMultipleRecipients( szCC, pMessage->m_CC);
		if( !szBCC.IsEmpty() )
			pMessage->ParseMultipleRecipients( szBCC, pMessage->m_BCC);
		if( !szSubject.IsEmpty() )
			pMessage->m_sSubject = szSubject;
		if( !szBody.IsEmpty() )
			pMessage->AddHTMLBody( szBody, _T("") );

		//Add the attachment(s) if necessary
		if( !szAttach.IsEmpty()) 
			pMessage->AddMultipleAttachments( szAttach );		

		//Setup the from address
		if( szName.IsEmpty() )
		{
			pMessage->m_From = szFrom;
			pMessage->m_ReplyTo = szFrom;
		}
		else
		{
			CPJNSMTPAddress address( szName, szFrom );
			pMessage->m_From = address;
			pMessage->m_ReplyTo = address;
		}
		//comment this line out if you want to send a X-Mailer header
		pMessage->m_sXMailer.Empty();

		// check DSN
		if( m_bDSN )
		{
			pMessage->m_DSNReturnType = CPJNSMTPMessage::FullEmail;
			pMessage->m_DSN = 0;
			//if( m_bDSNSuccess )
			//	pMessage->m_DSN |= CPJNSMTPMessage::DSN_SUCCESS;
			//if(m_bDSNFailure )
			//	pMessage->m_DSN |= CPJNSMTPMessage::DSN_FAILURE;
			//if (m_bDSNDelay)
			//	pMessage->m_DSN |= CPJNSMTPMessage::DSN_DELAY;
		}
		else
			pMessage->m_DSN = static_cast<DWORD>( CPJNSMTPMessage::DSN_NOT_SPECIFIED );

		//Disconnect if already connected
		if( connection.IsConnected() )
			connection.Disconnect();

		//Auto connect to the internet?
		if( bAutoDial )
			connection.ConnectToInternet();

		// check port
		if( appConfig.m_Email.nSMTPPort == 0 )
			appConfig.m_Email.nSMTPPort = 25;

#ifndef CPJNSMTP_NOSSL
		connection.Connect(sHost, m_Auth, m_sUsername, m_sPassword, m_nPort, m_bSSL);
#else
		// use name specified in INI file
		if( !appConfig.m_Email.szEmailUser.IsEmpty() )
			connection.Connect( appConfig.m_Email.szSMTPServer, CPJNSMTPConnection::AUTH_AUTO, appConfig.m_Email.szEmailUser, appConfig.m_Email.szEmailPassword, appConfig.m_Email.nSMTPPort );
		else
			connection.Connect( appConfig.m_Email.szSMTPServer, CPJNSMTPConnection::AUTH_NONE, szFrom, _T(""), appConfig.m_Email.nSMTPPort );
#endif
		// send message
		connection.SendMessage( *pMessage );

		//Auto disconnect from the internet
		if( bAutoDial )
			connection.CloseInternetConnection();

		// message sent
		bRetVal = TRUE;
	}
	catch( CPJNSMTPException* pEx )
	{
		//Display the error
		CString sMsg;
		if( HRESULT_FACILITY( pEx->m_hr ) == FACILITY_ITF )
			sMsg.Format(_T("An error occured sending the message, Error:%08X\nDescription:%s"), pEx->m_hr, pEx->GetErrorMessage().operator LPCTSTR());
		else
			sMsg.Format(_T("An error occured sending the message, Error:%08X\nDescription:%s, Response:%s"), pEx->m_hr, pEx->GetErrorMessage().operator LPCTSTR(), pEx->m_sLastResponse.operator LPCTSTR());
		AfxMessageBox(sMsg, MB_ICONSTOP);

		pEx->Delete();
		// not sent
		bRetVal = FALSE;
	}

	//Tidy up the heap memory
	if (pMessage)
	delete pMessage;

	WSACleanup();
	return bRetVal;
}
